import sys
import signal
import logging
import re
from pathlib import Path
import config
from utils import setup_logging, handle_interrupt, perform_cleanup
from test_case_handler import run_test_case
from report_generator import generate_summary
import os
import time
from device_manager import connect_device_android
import argparse

# 全局日志文件路径
GLOBAL_LOG_FILE = Path(__file__).parent / "execution.log"


def get_test_cases():
    """
    13.调用本地相机拍摄视频,建议将视频拍摄好然后屏蔽代码调用拍摄
    15.创作页面目前未选择素材不展示下一步按钮，所以此用例暂时废弃
    22.添加两条高帧率视频10分钟,处理时间太久需要10分钟
    25.由于前面16-24用例场景有覆盖用例25，且拍摄视频素材耗时比较久，所以暂时废弃此用例执行
    45.demo包并无模板功能，所以用例里暂时废弃
    """
    # 执行用例集
    exclude_pattern = re.compile(r"TC000013|TC000015|TC000022|TC000025|TC000045|ces\.air")

    # exclude_pattern = re.compile(r"TC000013|TC00001[5-9]|TC00002[0-5]|TC000033|TC000045|ces\.air")
    # 调试报告的用例集
    # exclude_pattern = re.compile(r"TC000013|TC000015|TC00002[0-9]|TC00003[0-9]|TC00004[0-9]|TC00005[0-9]|TC00006[0-9]|TC00007[0-9]|TC00008[0-9]|TC00009[0-9]|TC000010[0-9]|TC000011[0-9]|TC000012[0-9]|ces\.air")
    cases = []

    air_dir = config.AIR_DIR
    if not air_dir.exists():
        logging.getLogger().error(f"❌ 测试用例目录不存在: {air_dir}")
        return []

    logging.getLogger().info(f"扫描测试用例目录: {air_dir}")

    for case_dir in air_dir.glob("*.air"):
        case_name = case_dir.name
        if exclude_pattern.search(case_name):
            logging.getLogger().debug(f"排除无效用例: {case_name}")
            continue
        cases.append(case_dir)

    def extract_number(case_dir):
        match = re.search(r'\d+', case_dir.name)
        if match:
            return int(match.group())
        return 0

    cases.sort(key=extract_number)
    logging.getLogger().info(f"发现有效测试用例总数: {len(cases)} 个")
    return cases


def main():
    # 解析命令行参数
    parser = argparse.ArgumentParser(description='执行自动化测试')
    parser.add_argument('--no-logcat', action='store_true', help='禁用logcat日志抓取')
    parser.add_argument('--no-perf', action='store_true', help='禁用性能监控')
    args = parser.parse_args()

    # 根据命令行参数覆盖配置
    if args.no_logcat:
        config.ENABLE_LOGCAT = False
        logger = logging.getLogger()
        logger.info("⏭️ 已通过命令行禁用Logcat日志抓取")

    if args.no_perf:
        config.ENABLE_PERF_MONITOR = False
        logger = logging.getLogger()
        logger.info("⏭️ 已通过命令行禁用性能监控")

    # 记录脚本开始时间
    script_start_time = time.time()
    # 增强日志设置，添加文件处理器
    setup_logging(GLOBAL_LOG_FILE)  # 传入日志文件路径
    logger = logging.getLogger()

    signal.signal(signal.SIGINT, handle_interrupt)
    signal.signal(signal.SIGTERM, handle_interrupt)

    try:
        # 使用自动选择并连接设备功能
        dev = connect_device_android()
        if not dev:
            logger.error("❌ 未找到可用设备，程序终止")
            sys.exit(1)

        logger.info(f"✅ 设备连接成功: {dev.serialno}")

        # 确保基准图目录存在
        config.BASELINE_DIR.mkdir(parents=True, exist_ok=True)

        if not config.BASELINE_PATH.exists():
            dev.snapshot(str(config.BASELINE_PATH))
            logger.success(f"基准图已保存: {config.BASELINE_PATH}")
        else:
            logger.info(f"使用现有基准图: {config.BASELINE_PATH}")
    except Exception as e:
        logger.error(f"❌ 设备连接或基准图生成失败: {str(e)}")
        sys.exit(1)

    test_cases = get_test_cases()
    if not test_cases:
        logger.error("❌ 未找到有效测试用例，程序终止")
        sys.exit(1)

    execution_results = {}

    # 第一轮执行用例
    # 第二轮执行用例（只执行失败的用例）
    failed_cases = []

    # 保存原始工作目录
    original_cwd = os.getcwd()

    try:
        # 第一轮执行
        for idx, case_path in enumerate(test_cases, 1):
            if config.INTERRUPTED:
                logger.info("检测到中断信号，终止后续用例执行...")
                break

            logger.info(f"执行进度 ({idx}/{len(test_cases)}): {case_path.name}")

            # 进入用例目录
            os.chdir(case_path)

            # 执行测试用例
            (status, log_url, report_url,
             logcat_log_url, perf_report_url, performance_data,
             perf_data_points, duration, exceeded_thresholds) = run_test_case(case_path, dev)

            # 返回原始工作目录
            os.chdir(original_cwd)

            # 记录执行结果
            result = {
                "status": "通过" if status else "失败",
                "log_url": log_url,
                "report_url": report_url,
                "logcat_url": logcat_log_url,
                "perf_url": perf_report_url,
                "performance_data": performance_data,
                "perf_data_points": perf_data_points,
                "duration": duration,
                "exceeded_thresholds": exceeded_thresholds,
                "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
            }

            # 初始化用例结果列表
            if case_path.name not in execution_results:
                execution_results[case_path.name] = []

            execution_results[case_path.name].append(result)

            if not status:
                failed_cases.append(case_path)
                # 安全获取异常信息
                error_reason = str(e) if 'e' in locals() else "未知错误"

        # 第二轮重试失败用例
        if failed_cases:
            logger.info(f"\n🔁 开始重试 {len(failed_cases)} 个失败用例...")
            for case_path in failed_cases:
                if config.INTERRUPTED:
                    break

                logger.info(f"重试用例: {case_path.name}")

                # 进入用例目录
                os.chdir(case_path)

                # 执行重试
                (status, log_url, report_url,
                 logcat_log_url, perf_report_url, performance_data, perf_data_points, duration,
                 exceeded_thresholds) = run_test_case(case_path, dev, is_retry=True)

                # 返回原始工作目录
                os.chdir(original_cwd)

                # 记录重试结果
                result = {
                    "status": "通过" if status else "失败",
                    "log_url": log_url,
                    "report_url": report_url,
                    "logcat_url": logcat_log_url,
                    "perf_url": perf_report_url,
                    "performance_data": performance_data,
                    "perf_data_points": perf_data_points,
                    "duration": duration,
                    "exceeded_thresholds": exceeded_thresholds,
                    "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
                    "is_retry": True  # 标记为重试执行
                }

                execution_results[case_path.name].append(result)

                if status:  # 更新结果
                    logger.success(f"✅ 重试成功: {case_path.name}")

    except Exception as e:
        logger.error(f"❌ 全局异常: {str(e)}")
        import traceback
        logger.debug(traceback.format_exc())
    finally:
        # 计算总执行时长
        total_duration = time.time() - script_start_time

        # 确保工作目录恢复
        os.chdir(original_cwd)

        # 只调用一次 generate_summary 并传递总时长
        summary_report_url = generate_summary(execution_results, total_duration)

        if summary_report_url:
            logger.info(f"📊 汇总报告: {summary_report_url}")

        # 计算通过和失败的用例数量
        passed_count = 0
        failed_count = 0
        for case_name, results in execution_results.items():
            # 取最后一次执行结果作为最终状态
            final_status = results[-1]["status"]
            if final_status == "通过":
                passed_count += 1
            else:
                failed_count += 1

        logger.info(
            f"测试执行完成，共执行 {len(execution_results)} 个用例，通过 {passed_count} 个，失败 {failed_count} 个。")

        # 执行清理操作
        if dev:
            perform_cleanup(dev)

        # 确保日志文件关闭
        for handler in logging.getLogger().handlers:
            if isinstance(handler, logging.FileHandler):
                handler.close()
        sys.exit(0)


if __name__ == "__main__":
    main()